/**
 * 
 */
package org.pandazxx.picasamanager.helper;

import java.io.IOException;
import java.io.PrintStream;
import java.io.StringWriter;
import java.util.List;
import java.util.Vector;

import org.apache.log4j.Logger;
import org.pandazxx.test.TestArgs;

import com.martiansoftware.jsap.JSAP;
import com.martiansoftware.jsap.JSAPException;
import com.martiansoftware.jsap.JSAPResult;

/**
 * @author pandazxx
 * 
 */
public class Arguments {
	private static final Logger logger = Logger.getLogger(Arguments.class);

	private String loginUsername;

	private String loginPassword;

	private String operUsername;

	private String albumName;

	private String[] filenameList;

	private boolean verbose;

	private boolean help;

	private Operation operation;

	public enum Operation {
		Upload("upload"), List("list"), AddAlbum("add-album"), DelAblum(
				"delete-album");
		// TODO add more operations

		public final String name;

		Operation(String name) {
			this.name = name;
		}

		public static Operation getOperation(String name) {
			for (Operation o : Operation.values()) {
				if (o.name.equals(name)) {
					return o;
				}
			}
			return null;
		}
	}

	/**
	 * @return the loginUsername
	 */
	public String getLoginUsername() {
		return loginUsername;
	}

	/**
	 * @return the loginPassword
	 */
	public String getLoginPassword() {
		return loginPassword;
	}

	/**
	 * @return the operUsername
	 */
	public String getOperUsername() {
		return operUsername;
	}

	/**
	 * @return the albumName
	 */
	public String getAlbumName() {
		return albumName;
	}

	/**
	 * @return the filenameList
	 */
	public String[] getFilenameList() {
		return filenameList;
	}

	/**
	 * @return the verbose
	 */
	public boolean isVerbose() {
		return verbose;
	}

	/**
	 * @return the help
	 */
	public boolean isHelp() {
		return help;
	}

	/**
	 * @return the operation
	 */
	public Operation getOperation() {
		return operation;
	}

	private Arguments(JSAPResult config) throws IllegalArgument {
		loginUsername = config.getString("login");
		loginPassword = readPassword(config);
		operUsername = config.getString("oper_username", loginUsername);
		albumName = config.getString("album");
		verbose = config.getBoolean("verbose");
		help = config.getBoolean("help", false);
		String _operation = config.getString("operation");
		operation = Operation.getOperation(_operation);
		if (operation == null) {
			String errmsg = "Illegal operation value '" + _operation + "'. "
					+ "Option values are: ";
			for (Operation o : Operation.values()) {
				errmsg += o.name + "\n";
			}
			throw new IllegalArgument(errmsg);
		}
		if (operation.equals(Operation.Upload)) {
			filenameList = config.getStringArray("filename");
			if (filenameList == null || filenameList.length == 0) {
				throw new IllegalArgument("Filename required");
			}
		}
	}

	/**
	 * @param config
	 * @return
	 * @throws IllegalArgument 
	 */
	private String readPassword(JSAPResult config) throws IllegalArgument {
		String ret = config.getString("password");
		if (ret == null) {
			if (System.console() == null) {
				throw new IllegalArgument("Password is required");
			} else {
				char[] password = System.console().readPassword("Please input password:");
				if (password == null) {
					throw new IllegalArgument("Password is required");
				} else {
					ret = new String(password);
				}
			}
		}
		return ret;
	}

	@Override
	public String toString() {
		StringWriter writer = new StringWriter();
		writer.write("Login user name: " + loginUsername + "\n");
		writer.write("Login password: " + loginPassword + "\n");
		writer.write("Operation user name: " + operUsername + "\n");
		writer.write("Album name: " + albumName + "\n");
		writer.write("Verbose mode: " + (verbose ? "on" : "off") + "\n");
		writer.write("Operation: " + operation.name + "\n");

		writer.write("\nOperate file list:");
		for (String filename : filenameList) {
			writer.write("\t\t" + filename);
		}
		return writer.toString();
	}

	public void printLog() {
		logger.info("Login user name: " + loginUsername + "\n");
		logger.info("Login password: " + loginPassword + "\n");
		logger.info("Operation user name: " + operUsername + "\n");
		logger.info("Album name: " + albumName + "\n");
		logger.info("Verbose mode: " + (verbose ? "on" : "off") + "\n");
		logger.info("Operation: " + operation.name + "\n");

		if (filenameList != null && filenameList.length != 0) {
			logger.info("Operate file list:");
			for (String filename : filenameList) {
				logger.info("\t" + filename);
			}
		}
	}

	public static Arguments getArguments(String[] args) {
		Arguments ret;

		try {
			JSAP jsap = new JSAP(TestArgs.class.getResource("/argument.jsap"));

			JSAPResult config = jsap.parse(args);
			if (!config.success() && !config.getBoolean("help", false)
					&& !config.getBoolean("version", false)) {

				System.err.println();

				// print out specific error messages describing the problems
				// with the command line, THEN print usage, THEN print full
				// help. This is called "beating the user with a clue stick."
				for (java.util.Iterator errs = config.getErrorMessageIterator(); errs
						.hasNext();) {
					System.err.println("Error: " + errs.next());
				}

				System.err.println();
				System.err.println("Usage: java " + TestArgs.class.getName());
				System.err.println("                " + jsap.getUsage());
				System.err.println();
				System.err.println(jsap.getHelp());
				return null;
			}

			if (config.getBoolean("help", false)) {
				System.err.println("Usage: java " + TestArgs.class.getName());
				System.err.println("\t\t" + jsap.getUsage());
				System.err.println();
				System.err.println(jsap.getHelp());
				return null;
			}
			ret = new Arguments(config);

			if (ret.isVerbose()) {
				System.err.println("printing log");
				ret.printLog();
			}
			return ret;
		} catch (IllegalArgument e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JSAPException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}
